﻿using BonjourQuotation.DataAccess.Entity_Framework;
using BonjourQuotation.ObjectModel.AccountData;
using BonjourQuotation.ObjectModel.BusinessData;
using BonjourQuotation.ObjectModel.ErrorData;
using BonjourQuotation.ObjectModel.LoggerData;
using BonjourQuotation.ObjectModel.OptionalData;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BonjourQuotation.DataAccess.Repositories
{
    public class OptionalRepository : IOptionalRepository
    {
        private readonly BonDataEntities _context = new BonDataEntities();
        private readonly log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public ErrorBInfo CreateOptional(OptionalDetailsBData OptionalData)
        {
            ErrorBInfo Error = new ErrorBInfo();
            try
            {
                tblOptional NewOptional = new tblOptional()
                {
                    VendorID = OptionalData.SelectedVendorID,
                    ContractStartDate = OptionalData.ContractStartDate,
                    ContractEndDate = OptionalData.ContractEndDate,
                    ContractSignDate = OptionalData.ContractSignDate,
                    Description = OptionalData.Description,
                    Active = OptionalData.Active,

                };

                _context.tblOptionals.Add(NewOptional);
                _context.SaveChanges();
            }
            catch (Exception ex)
            {
                Error.errorCode = 100;
                Error.Message = ex.Message;
                logger.Error(ex.ToMessageAndCompleteStacktrace());
            }
            return Error;
        }
        public ErrorBInfo CreateOptionalDetailData(OptionalDetailsBData OptionalData)
        {
            ErrorBInfo Error = new ErrorBInfo();
            try
            {
                tblOptionalDetail newoptdetail = new tblOptionalDetail()
                {
                    OptionalID = OptionalData.OptionalID,
                    PaxFrom = OptionalData.PaxFrom,
                    PaxTo = OptionalData.PaxTo,
                    Currency = OptionalData.SelectedCurrency,
                    Price = OptionalData.Price,
                    BusIncluded = OptionalData.BusIncluded,
                    GuideIncluded = OptionalData.GuideIncluded,
                };
                _context.tblOptionalDetails.Add(newoptdetail);
                _context.SaveChanges();
            }
            catch (Exception ex)
            {
                Error.Message = ex.Message;
                logger.Error(ex.ToMessageAndCompleteStacktrace());
            }
            return Error;
        }
        public ManageOptionalsGridBData LoadAllOptionals(int PageNumber)
        {
            ManageOptionalsGridBData AllOptionals = new ManageOptionalsGridBData();
            AllOptionals.Rows = new List<ManageOptionalsGridRowBData>();
            AllOptionals.Rows = (from optional in _context.tblOptionals
                                 from vendor in _context.tblVendors
                                 where vendor.VendorID == optional.VendorID
                                 && vendor.Active == true
                                 orderby optional.ContractStartDate
                                 select new ManageOptionalsGridRowBData()
                                 {
                                     OptionalID = optional.OptionalID,
                                     Active = optional.Active,
                                     ContractStartDate = optional.ContractStartDate,
                                     ContractEndDate = optional.ContractEndDate,
                                     ContractSignDate = optional.ContractSignDate,
                                     Description = optional.Description,
                                     VendorID = vendor.VendorID,
                                     VendorName = vendor.VendorName,
                                     City = vendor.City,
                                 }).Take(PageNumber * ManageOptionalsGridBData.PageCount).ToList();
            AllOptionals.City = (from city in _context.tblCities
                               where city.Active == true
                               orderby city.City
                               select new
                               {
                                   Key = city.CityID,
                                   Value = city.City
                               }).ToDictionary(o => o.Key, o => o.Value);
            AllOptionals.Active = new Dictionary<bool, string>
            {
                {true,"Yes"},
                {false,"No"},
            };
            return AllOptionals;
        }
        public ManageOptionalsGridBData LoadSearchedOptionals(ManageOptionalsGridBData Data)
        {
            var FilterOptional = _context.tblOptionals.AsQueryable();
            if (Data.VendorName != null && Data.VendorName.Length > 0)
            {
                List<int> VendorIDs = new List<int>();
                VendorIDs = _context.tblVendors.Where(vnd => vnd.VendorName.Contains(Data.VendorName.Trim())).Select(vnd=>vnd.VendorID).ToList();
                if (VendorIDs != null && VendorIDs.Count != 0)
                    FilterOptional = FilterOptional.Where(opt => VendorIDs.Contains(opt.VendorID));
            }
            if (Data.SelectedCity != null)
            {
                List<int> VendorIDs = new List<int>();
                VendorIDs = _context.tblVendors.Where(vnd => vnd.City == Data.SelectedCity).Select(vnd => vnd.VendorID).ToList();
                if (VendorIDs != null && VendorIDs.Count != 0)
                    FilterOptional = FilterOptional.Where(opt => VendorIDs.Contains(opt.VendorID));
            }
            if (Data.SelectedActive != null)
                FilterOptional = FilterOptional.Where(opt => opt.Active == Data.SelectedActive);
            if (Data.ContractStartDate != null)
                FilterOptional = FilterOptional.Where(opt => opt.ContractStartDate >= Data.ContractStartDate);
            if (Data.ContractEndDate != null)
                FilterOptional = FilterOptional.Where(opt => opt.ContractEndDate <= Data.ContractEndDate);
            ManageOptionalsGridBData allOptionals;
            allOptionals = new ManageOptionalsGridBData();
            allOptionals.Rows = new List<ManageOptionalsGridRowBData>();
            allOptionals.Rows = (from optional in FilterOptional
                                 from vendor in _context.tblVendors
                                 where vendor.VendorID == optional.VendorID
                                 && vendor.Active == true
                                 orderby optional.ContractStartDate
                                 select new ManageOptionalsGridRowBData()
                                 {
                                     OptionalID = optional.OptionalID,
                                     Active = optional.Active,
                                     ContractStartDate = optional.ContractStartDate,
                                     ContractEndDate = optional.ContractEndDate,
                                     ContractSignDate = optional.ContractSignDate,
                                     Description = optional.Description,
                                     VendorID = vendor.VendorID,
                                     VendorName = vendor.VendorName,
                                     City = vendor.City,
                                 }).Take(Data.PageNum * ManageOptionalsGridBData.PageCount).ToList();
            allOptionals.City = (from city in _context.tblCities
                                 where city.Active == true
                                 orderby city.City
                                 select new
                                 {
                                     Key = city.CityID,
                                     Value = city.City
                                 }).ToDictionary(o => o.Key, o => o.Value);
            allOptionals.Active = new Dictionary<bool, string>
            {
                {true,"Yes"},
                {false,"No"},
            };
            return allOptionals;
        }
        public OptionalDetailsBData LoadOptionalDetailsByID(int OptionalID)
        {
            OptionalDetailsBData OptionalData = null;
            if (OptionalID == 0)
            {
                OptionalData = new OptionalDetailsBData();
                OptionalData.Rows = new List<OptionalDetailsRowBData>();
            }
            else
            {
                if (OptionalID == -1)
                {
                    OptionalID = _context.tblOptionals.Max(opt => opt.OptionalID);
                }
                OptionalData = (from opt in _context.tblOptionals
                                from vnd in _context.tblVendors
                                where opt.OptionalID == OptionalID
                                && vnd.VendorID == opt.VendorID
                                select new OptionalDetailsBData
                                {
                                    OptionalID = opt.OptionalID,
                                    SelectedVendorID = opt.VendorID,
                                    SelectedVendorName = vnd.VendorName,
                                    ContractStartDate = opt.ContractStartDate,
                                    ContractEndDate = opt.ContractEndDate,
                                    ContractSignDate = opt.ContractSignDate,
                                    Description = opt.Description,
                                    Active = opt.Active,
                                }).SingleOrDefault();
                OptionalData.Rows = (from optdet in _context.tblOptionalDetails
                                     where optdet.OptionalID == OptionalID
                                     select new OptionalDetailsRowBData
                                     {
                                         OptionalDetailID = optdet.OptionalDetailID,
                                         SelectedCurrency = optdet.Currency,
                                         PaxFrom = optdet.PaxFrom,
                                         PaxTo = optdet.PaxTo,
                                         Price = optdet.Price,
                                         BusIncluded = optdet.BusIncluded,
                                         GuideIncluded = optdet.GuideIncluded,
                                     }).ToList();
            }
            if (OptionalData.Rows == null)
                OptionalData.Rows = new List<OptionalDetailsRowBData>();
            OptionalData.Currency = new Dictionary<int, string>
            {
                {1,"USD"},
                {2,"CAD"},
            };
            return OptionalData;
        }
        public ErrorBInfo SaveOptionalsGridData(ManageOptionalsGridBData Data)
        {
            ErrorBInfo Error = new ErrorBInfo();
            try
            {
                List<int> OptionalIDs = Data.Rows.Select(Opt => Opt.OptionalID).ToList();
                var SaveEntityOptionals = _context.tblOptionals.Where(opt => OptionalIDs.Contains(opt.OptionalID)).ToList();
                foreach (var Optional in SaveEntityOptionals)
                {
                    var SaveData = Data.Rows.Where(data => data.OptionalID == Optional.OptionalID).SingleOrDefault();
                    if (SaveData != null)
                    {
                        Optional.Active = SaveData.Active;
                    }
                }
                _context.SaveChanges();
            }
            catch (Exception ex)
            {
                Error.Message = ex.Message;
                logger.Error(ex.ToMessageAndCompleteStacktrace());
            }
            return Error;
        }
        public ErrorBInfo SaveOptionalDetailsData(OptionalDetailsBData Data)
        {
             ErrorBInfo Error = new ErrorBInfo();
             using (var transaction = _context.Database.BeginTransaction(IsolationLevel.Serializable))
             {
                 try
                 {
                     var EditOptional = (from optional in _context.tblOptionals where optional.OptionalID == Data.OptionalID select optional).SingleOrDefault();
                     if (EditOptional != null)
                     {
                         EditOptional.VendorID = Data.SelectedVendorID;
                         EditOptional.ContractStartDate = Data.ContractStartDate;
                         EditOptional.ContractEndDate = Data.ContractEndDate;
                         EditOptional.ContractSignDate = Data.ContractSignDate;
                         EditOptional.Description = Data.Description;
                         EditOptional.Active = Data.Active;

                         List<int> OptionalDetIDs = Data.Rows.Select(Opt => Opt.OptionalDetailID).ToList();
                         var SaveEntityOptionalDetails = _context.tblOptionalDetails.Where(opt => OptionalDetIDs.Contains(opt.OptionalDetailID)).ToList();
                         foreach (var OptDet in SaveEntityOptionalDetails)
                         {
                             var SaveData = Data.Rows.Where(data => data.OptionalDetailID == OptDet.OptionalDetailID).SingleOrDefault();
                             if (SaveData != null)
                             {
                                 OptDet.PaxTo = SaveData.PaxTo;
                                 OptDet.PaxFrom = SaveData.PaxFrom;
                                 OptDet.Currency = SaveData.SelectedCurrency;
                                 OptDet.Price = SaveData.Price;
                                 OptDet.BusIncluded = SaveData.BusIncluded;
                                 OptDet.GuideIncluded = SaveData.GuideIncluded;
                             }
                         }
                         _context.SaveChanges();
                         transaction.Commit();
                     }
                     else
                     {
                         Error.errorCode = 130;
                         Error.Message = "Optional Can`t be found:";
                     }
                 }
                 catch (Exception ex)
                 {
                     Error.errorCode = 130;
                     Error.Message = ex.Message;
                     logger.Error(ex.ToMessageAndCompleteStacktrace());
                 }
             }
            return Error;
        }
        public void Dispose()
        {
            _context.Dispose();
        }
    }
}
